package com.virtualparadigm.compositor;

import java.io.Serializable;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;

import com.virtualparadigm.identity.Identifiable;
import com.virtualparadigm.identity.ResourceIdentifier;

public abstract class CompositorDelegate<CompositorType extends Identifiable> implements Serializable
{
	private static final long serialVersionUID = 1L;
	
	// why compositor does not implement Identifiable like CompositorType?
	//	- b/c compositor class is NOT extended. other objects can have many instances of this
	//	  Not the same story for compsite part!
	
	// Why need "wrapped" Compositor instance?
	//   - b/c compositor is implemented via composition, composite part uses inheritance
	private CompositorType compositor;
	
	public CompositorDelegate(CompositorType instance)
	{
		this.setCompositor(instance);
	}
	
	public CompositorType getCompositor()
	{
		return compositor;
	}
	private void setCompositor(CompositorType instance)
	{
		this.compositor = instance;
	}
	
	// ================================================
	// ABSTRACT METHODS
	// ================================================
	public abstract boolean removeCompositePart(ResourceIdentifier resourceIdentifier);
	public abstract boolean putCompositePart(CompositePart<CompositorType> compositePart);
	
	// ================================================
	// UTILITY METHODS
	// ================================================
	public String toString()
	{
		return ReflectionToStringBuilder.toString(this, ToStringStyleBuilder.toStringStyle);
	}
	public int hashCode()
	{
		HashCodeBuilder builder = new HashCodeBuilder();
	    builder.append(this.getCompositor().getResourceIdentifier());
	    return builder.toHashCode();		
	}
	public boolean equals(Object obj)
	{
		if (obj == null)
		{
			return false;
		}
		if (obj == this)
		{
			return true;
		}
		if (obj.getClass() != getClass())
		{
			return false;
		}
		CompositorDelegate<CompositorType> that = (CompositorDelegate<CompositorType>)obj;
		EqualsBuilder builder = new EqualsBuilder();
	    builder.append(this.getCompositor().getResourceIdentifier(), that.getCompositor().getResourceIdentifier());
		return builder.isEquals();
	}
	
}